﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace FlockTest
{
        public class Vector
        {
            #region Private members
            private float x;
            private float y;
            private float z;
            #endregion

            #region Constructors
            public Vector() { }

            public Vector(float X, float Y, float Z)
            {
                x = X;
                y = Y;
                z = Z;
            }
            #endregion

            #region Public properties
            public float X { get { return x; } set { x = value; } }
            public float Y { get { return y; } set { y = value; } }
            public float Z { get { return z; } set { z = value; } }

            public static Vector Zero { get { return new Vector(0.0f, 0.0f, 0.0f); } }
            
            public static Vector XAxis { get { return new Vector(1.0f, 0.0f, 0.0f); } }
            public static Vector YAxis { get { return new Vector(0.0f, 1.0f, 0.0f); } }
            public static Vector ZAxis { get { return new Vector(0.0f, 0.0f, 1.0f); } }
            #endregion

            #region Methods
            public static Vector Add(Vector vector1, Vector vector2)
            {
                if ((object)vector1 == null || (object)vector2 == null) return null;
                return new Vector(vector1.X + vector2.X, vector1.Y + vector2.Y, vector1.Z + vector2.Z);
            }

            public static Vector Subtract(Vector vector1, Vector vector2)
            {
                if ((object)vector1 == null || (object)vector2 == null) return null;
                return new Vector(vector1.X - vector2.X, vector1.Y - vector2.Y, vector1.Z - vector2.Z);
            }

            public static Vector Negate(Vector vector)
            {
                if ((object)vector == null) return null;
                return new Vector(-vector.X, -vector.Y, -vector.Z);
            }

            public static Vector Multiply(Vector vector, float val)
            {
                if ((object)vector == null) return null;
                return new Vector(vector.X * val, vector.Y * val, vector.Z * val);
            }

            public static Vector Divide(Vector vector, float val)
            {
                if ((object)vector == null) return null;
                return new Vector(vector.X / val, vector.Y / val, vector.Z / val);
            }

            public static float Magnitude(Vector vector)
            {
                return (float)Math.Sqrt( vector.x * vector.x + vector.y * vector.y + vector.z * vector.z );
            }

            #endregion

            #region Operators
            public static bool operator ==(Vector vector1, Vector vector2)
            {
                if ((object)vector1 == null || (object)vector2 == null) return false;
                return ((vector1.X.Equals(vector2.X)) && (vector1.Y.Equals(vector2.Y)) && (vector1.Z.Equals(vector2.Z)));
            }

            public static bool operator !=(Vector vector1, Vector vector2)
            {
                if ((object)vector1 == null || (object)vector2 == null) return false;
                return ((!vector1.X.Equals(vector2.X)) && (!vector1.Y.Equals(vector2.Y)) && (!vector1.Z.Equals(vector2.Z)));
            }

            public static Vector operator +(Vector vector1, Vector vector2)
            {
                if ((object)vector1 == null || (object)vector2 == null) return null;
                return Vector.Add(vector1, vector2);
            }

            public static Vector operator -(Vector vector1, Vector vector2)
            {
                if ((object)vector1 == null || (object)vector2 == null)  return null;
                return Vector.Subtract(vector1, vector2);
            }

            public static Vector operator -(Vector vector)
            {
                if ((object)vector == null) return null;
                return Vector.Negate(vector);
            }

            public static Vector operator *(Vector vector, float val)
            {
                if ((object)vector == null) return null;
                return Vector.Multiply(vector, val);
            }

            public static Vector operator /(Vector vector, float val)
            {
                if ((object)vector == null) return null;
                return Vector.Divide(vector, val);
            }
            #endregion

            #region Overides
            public override bool Equals(object obj)
            {
                Vector vector = obj as Vector;
                if ((Object)vector != null) return (x.Equals(vector.X)) && (y.Equals(vector.Y)) && (z.Equals(vector.Z));
                return false;
            }

            public override string ToString() { return string.Format("({0}, {1}, {2})", x, y, z); }
            public override int GetHashCode() { return x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode(); }
            #endregion
        }
    
}
